/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package motorprediccion;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Random;
import modeloprediccion.Modelo;
import modeloprediccion.ModeloPredictorCorrector;
import umontreal.iro.lecuyer.probdist.NormalDist;

/**
 *
 * @author dani
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws SQLException {
        DataLoader dataloader = new DataLoader();
        ArrayList<Recorrido> recorridos = dataloader.cargarRecorridos();
        ArrayList<DatoPosicional> nuevosDatos = dataloader.obtenerDatosPosicionales();
        HashMap colectivos = new HashMap();
        HashMap promedios = dataloader.cargarPromedios();
        HashMap desvEstandar = dataloader.cargarDesv();
        int cantidadIndefiniciones = 0, cantidadDefiniciones = 0, cantidaddatos = nuevosDatos.size();
        ArrayList<DatoProcesado> datosProcesados;
        
        //ModeloPrediccion analizador = new ModeloPrediccion(recorridos.get(1));
        Modelo analizador = new ModeloPredictorCorrector();
        analizador.setRecorridos(recorridos);
        analizador.estimarTiempos(nuevosDatos);
                
        for(int i = 0; i < nuevosDatos.size(); i++) {
            int idcolectivo = nuevosDatos.get(i).getIdColectivo();
            System.out.println();
            System.out.println("Posicion"+nuevosDatos.get(i).getPosicion()+" Fecha"+nuevosDatos.get(i).getFecha().getTime().toString());
            if(colectivos.containsKey(idcolectivo)) {
                Colectivo c = (Colectivo) colectivos.get(idcolectivo);
                int idlinea = 0;
                for (int j=0; j< recorridos.size();j++){
                    if (c.getRecorrido()== recorridos.get(j).getId())
                        idlinea = j;
                }
                datosProcesados = c.procesarNuevoDato(nuevosDatos.get(i));
                if(c.obtenerParadaActual() != null) {
                    System.out.println(c.obtenerParadaActual().getId()+ "  "+ recorridos.get(idlinea).obtenerOrden(c.obtenerParadaActual()));
                    System.out.println("Distancia a la parada "+nuevosDatos.get(i).calcularDistancia(c.obtenerParadaActual().getPosicion()));
                    cantidadDefiniciones++;
                }
                else {
                    System.out.println("Ninguna");
                    cantidadIndefiniciones++;
                }
            }
            else {
                colectivos.put(idcolectivo, new Colectivo(idcolectivo,recorridos.get(3)));

                Colectivo c = (Colectivo) colectivos.get(idcolectivo);
                datosProcesados = c.procesarNuevoDato(nuevosDatos.get(i));
                int idlinea = 0;
                for (int j=0; j< recorridos.size();j++){
                    if (c.getRecorrido()== recorridos.get(j).getId())
                        idlinea = j;
                }
                if(c.obtenerParadaActual() != null) {
                    System.out.println(c.obtenerParadaActual().getId()+ "  "+ recorridos.get(idlinea).obtenerOrden(c.obtenerParadaActual()));
                    cantidadDefiniciones++;
                }
                else {
                    System.out.println("Ninguna");
                    cantidadIndefiniciones++;
                }
            }
            if(datosProcesados != null) {
               analizador.procesarDatos(datosProcesados);

//               dataloader.guardarDatosProcesados(datosProcesados);
                //for(int t = 0; t < datosProcesados.size(); t++)
 //                   estimarArribos(datosProcesados.get(datosProcesados.size()-1),recorridos.get(0),promedios,dataloader);
   //                 estimarArribosNormal(datosProcesados.get(datosProcesados.size()-1),recorridos.get(0),promedios,desvEstandar,dataloader);
            }
        }

        System.out.println();
        System.out.println("Def, indef, %aciertos");
        System.out.println(cantidadDefiniciones+","+cantidadIndefiniciones+" "+cantidadDefiniciones*100/(cantidadDefiniciones+cantidadIndefiniciones));
    }

    public static void estimarArribos(DatoProcesado datoActual, Recorrido r, HashMap promedio, DataLoader d)     {
        //inicializacion
        int paradaActualN = r.obtenerOrden(datoActual.getParada());
        GregorianCalendar fecha = new GregorianCalendar();
        fecha.set(GregorianCalendar.YEAR, datoActual.getHoraArribo().get(GregorianCalendar.YEAR));
        fecha.set(GregorianCalendar.MONTH, datoActual.getHoraArribo().get(GregorianCalendar.MONTH));
        fecha.set(GregorianCalendar.DATE, datoActual.getHoraArribo().get(GregorianCalendar.DATE));
        fecha.set(GregorianCalendar.HOUR_OF_DAY, datoActual.getHoraArribo().get(GregorianCalendar.HOUR_OF_DAY));
        fecha.set(GregorianCalendar.MINUTE, datoActual.getHoraArribo().get(GregorianCalendar.MINUTE));
        fecha.set(GregorianCalendar.SECOND, datoActual.getHoraArribo().get(GregorianCalendar.SECOND));
        double tiempo = 0;

        for(int i = paradaActualN; i < r.getCantidadParadas(); i++) {
            tiempo = (Double) promedio.get(i+1);
            fecha.add(GregorianCalendar.SECOND, (int) tiempo);
            d.guardarPrediccion(datoActual.getIdcolectivo(), paradaActualN, i, datoActual.getHoraArribo(), fecha);
        }
    }

    public static void estimarArribosNormal(DatoProcesado datoActual, Recorrido r, HashMap promedio, HashMap desviacion, DataLoader d)     {
        //inicializacion
        int paradaActualN = r.obtenerOrden(datoActual.getParada());
        GregorianCalendar fecha = new GregorianCalendar();
        fecha.set(GregorianCalendar.YEAR, datoActual.getHoraArribo().get(GregorianCalendar.YEAR));
        fecha.set(GregorianCalendar.MONTH, datoActual.getHoraArribo().get(GregorianCalendar.MONTH));
        fecha.set(GregorianCalendar.DATE, datoActual.getHoraArribo().get(GregorianCalendar.DATE));
        fecha.set(GregorianCalendar.HOUR_OF_DAY, datoActual.getHoraArribo().get(GregorianCalendar.HOUR_OF_DAY));
        fecha.set(GregorianCalendar.MINUTE, datoActual.getHoraArribo().get(GregorianCalendar.MINUTE));
        fecha.set(GregorianCalendar.SECOND, datoActual.getHoraArribo().get(GregorianCalendar.SECOND));

        for(int i = paradaActualN; i < r.getCantidadParadas(); i++) {
            NormalDist distribucion=new NormalDist((Double) promedio.get(i+1),(Double) desviacion.get(i+1));
            double tiempo = distribucion.inverseF(new Random().nextDouble());
            fecha.add(GregorianCalendar.SECOND, (int) tiempo);
            d.guardarPrediccionNormal(datoActual.getIdcolectivo(), paradaActualN, i, datoActual.getHoraArribo(), fecha);
        }
    }
}
